package dalgo.main;

import java.io.PrintWriter;

import uniandes.cupi2.collections.arbol.arbolBinario.ArbolBinario;
import uniandes.cupi2.collections.iterador.Iterador;
import dalgo.utils.Utils;

public class Estado implements Comparable<Estado> {

	
	private String nombreTransicion;
	
	/**
	 * Arbol que modela el nodo (de grafo imaginario)
	 */
	private ArbolBinario<String> arbol;

	/**
	 * Funcion heuristica del estado modelado por este objeto
	 */
	private int funcionHeuristica;

	/**
	 * id de este estado
	 */
	private int id;

	/**
	 * id del estado padre, es decir, del nodo (de grafo imaginario) del cual
	 * este estado fue expandidio
	 */
	private int idPadre;

	/**
	 * atributo que modela si la variable esta en una sola de las ramas del
	 * arbol que modela este estado
	 */
	private boolean variableSola;

	/**
	 * Constructor de esta clase
	 * 
	 * @param arbol
	 *            arbol nuevo para el estado nuevo
	 * @param idPadre
	 *            identificador del estado del cuel este nacio
	 */
	public Estado(ArbolBinario<String> arbol, int idPadre, String nombre) {
		
		this.nombreTransicion = nombre;
		int idNodo = Main.darCuentaNodos();
		this.idPadre = idPadre;
		this.id = idNodo;
		this.arbol = arbol;
		evaluarArbol();

	}

	// --------------------------------------------------
	// Getters
	// --------------------------------------------------

	public ArbolBinario<String> getArbol() {
		return arbol;
	}

	public int getFuncionHeuristica() {
		return funcionHeuristica;
	}

	public int getId() {
		return id;
	}

	public int getIdPadre() {
		return idPadre;
	}

	public boolean isVariableSola() {
		return variableSola;
	}

	/**
	 * Imprime en postorden el arbol del estado modelado por este objeto
	 */
	public void imprimir(PrintWriter pw) {
		Iterador<String> i = arbol.darPostorden();
		String linea = "";
		while (i.haySiguiente()) {

			linea += i.darSiguiente()+" ";
		}
		
		pw.println(linea);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(Estado o) {
		if (getFuncionHeuristica() > o.getFuncionHeuristica())
			return 1;
		else if (getFuncionHeuristica() == o.getFuncionHeuristica())
			return 0;
		else
			return -1;
	}

	/**
	 * Calcula el valor de la heuristica dados ciertos parametros
	 * 
	 * @return un entero que modela el valor de la funcion heuristica
	 */
	private int calcularHeuristica() {

		int heuristica = 0;

		if (variableSola) {
			heuristica += 15;
		}

		heuristica += arbol.contarHojas();
		heuristica += arbol.darPeso();
		heuristica += Utils.contarCantVariables( arbol.darRaiz());

		return heuristica;

	}

	/**
	 * Evalua que tan viable es este estado para expansion
	 */
	private void evaluarArbol() {
		
		
		variableSola = Utils.variableSola(Main.getVariable(), arbol);
		funcionHeuristica = calcularHeuristica();
	}

	public String getNombreTransicion() {
		return nombreTransicion;
	}
	
	
	

}
